package com.fingard.dsp.bank.directbank.cmb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.paynotice.NoticeDataHelper;
import com.fingard.dsp.bank.dbobj.paynotice.SinglePayNotice;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqQrySglBatPayDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.dsp.basicbankdata.ebank.EBankData;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

/**
 * CMB01-中国招商银行银企直联
 * <p>
 * 单笔支付接口实现
 */
@Component("CMB01SinglePay")
public class CMB01SinglePay extends CMB01Base implements ISinglePay {
    /**
     * 单笔付款指令提交
     * @param p_req1908
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        // 由于招行前置机队列数较小，未减少并发，设置线程等待时间
        String isSetSleep = getBankConfig().getValueAsString("useSleepGetPay");
        if ("true".equals(isSetSleep.toLowerCase())) {
            long realSleepTime = getBankConfig().getValueAsInt("PaySleepTime");
            if (realSleepTime < 0) {
                realSleepTime = 0;
            }
            Thread.sleep(realSleepTime * 1000);
        }

        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetDetail;

        if ("190801".equals(p_req1908.reqHeader.commandCode) || "190802".equals(p_req1908.reqHeader.commandCode)) {
            if (getBankConfig().getValueAsBool("useOldSglPay")) {
                tmpRetDetail = d_190802_Payment(p_req1908);
            } else {
                tmpRetDetail = d_190802_DCPAYMNT(p_req1908);
            }
        } else if ("190802DCPAY".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190802_DCPAYMNT(p_req1908);
        } else if ("190804".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_1908_AgentRequest(p_req1908);
        } else if ("190805".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190805(p_req1908);
        } else {
            tmpRetDetail = new RetAtsSglDetail(p_req1908);
            tmpRetDetail.respCode = "0";
            tmpRetDetail.respInfo = "不支持的线路指令:" + p_req1908.reqHeader.commandCode;
            tmpRetDetail.transState = PaymentState.FAIL_Payment;
            tmpRetDetail.payInfoCode = FailCode.E9981;
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    /**
     * 21.2.1.网银贷记 NTIBCOPR
     *
     * @param p_req1908
     * @return
     * @throws Exception
     */
    private RetAtsSglDetail d_190805(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        CMB01Header tmpBnkHeader = new CMB01Header();
        tmpBnkHeader.FUNNAM = "NTIBCOPR";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter, tmpBnkHeader);

        xmlWriter.writeStartElement("NTOPRMODX");
        CMB01OtherElse tmpOtherElse = new CMB01OtherElse();
        tmpOtherElse.reqHeader = p_req1908.reqHeader;
        tmpOtherElse.bankFront = this.bankFront;
        tmpOtherElse.sbLog = this.sbLog;
        String busmod = getBankConfig().getMapValueByKey("busmodN31010", p_req1908.singleDetail.useType);
        xmlWriter.writeElementString("BUSMOD", busmod);
        xmlWriter.writeEndElement();
        //需要进行对账码拼接以及节点解析，采用XElement进行处理
        XElement tmpXElement = new XElement("NTIBCOPRX", "");
        ReqPayRecDetail p_atsDetail = p_req1908.singleDetail;
        String tmpSQRNBR = "";
        if (p_atsDetail.askNumber.length() > 6) {
            tmpSQRNBR = p_atsDetail.askNumber.substring(p_atsDetail.askNumber.length() - 6, p_atsDetail.askNumber.length());
        }
        tmpSQRNBR += "0001";
        tmpXElement.addChild(new XElement("SQRNBR", tmpSQRNBR));//流水号
        tmpXElement.addChild(new XElement("BBKNBR", "CB"));//付款账号银行号
        if (p_atsDetail.isVirtual) {
            String higherLevelAct = getBankConfig().getMapValueByKey("higherLevelAct", p_atsDetail.payAct);
            if (StringHelper.hasAnyChar(higherLevelAct)) {
                tmpXElement.addChild(new XElement("ACCNBR", higherLevelAct));//付款账号
            } else {
                retDetail.respCode = "0";
                retDetail.respInfo = "请求报文中ACCNBR节点为空，请检查CMB01/config.xml中'higherLevelAct'节点配置";
                return retDetail;
            }
        } else {
            tmpXElement.addChild(new XElement("ACCNBR", p_atsDetail.payAct));//付款账号
        }
        String tmpCNVNBR = getBankConfig().getMapValueByKey("ebankMappingCNVNBR", p_atsDetail.payAct);
        tmpXElement.addChild(new XElement("CNVNBR", tmpCNVNBR));//协议号
        tmpXElement.addChild(new XElement("YURREF", p_atsDetail.askNumber));//业务参考号
        tmpXElement.addChild(new XElement("CCYNBR", convertCurToBank(p_atsDetail.payCur)));//币种
        tmpXElement.addChild(new XElement("TRSAMT", p_atsDetail.payAmount));//金额
        tmpXElement.addChild(new XElement("CRTSQN", ""));//收方编号
        tmpXElement.addChild(new XElement("NTFCH1", ""));//通知方式一
        tmpXElement.addChild(new XElement("NTFCH2", ""));//通知方式二
        tmpXElement.addChild(new XElement("CDTNAM", p_atsDetail.recName));//收款人户名
        tmpXElement.addChild(new XElement("CDTEAC", p_atsDetail.recAct));//收款人账号
        String[] ebankCodeName = EBankData.mappingEBankCode(p_atsDetail.recBankCode, p_atsDetail.recStandardArea);
        if (ebankCodeName != null && ebankCodeName[0].length() > 0) {
            tmpXElement.addChild(new XElement("CDTBRD", ebankCodeName[0]));//收款行行号
        } else {
            tmpXElement.addChild(new XElement("CDTBRD", p_atsDetail.cnapsCode));//收款行行号
        }


        String[] srcNames = new String[]{"usage"};
        String[] trgNames = new String[]{"trstyp", "trscat"};
        String[] srcValues = new String[]{p_atsDetail.purpose};
        HashMap<String, String> tmpMap = getBankConfig().getMapAdvanceValues("ebankMappingTRSTYPCAT", srcNames, trgNames, srcValues);
        if (tmpMap == null || tmpMap.size() != 2) {
            retDetail.respCode = "0";
            retDetail.respInfo = "未获取到业务相关信息";
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = "E1301";
            return retDetail;
        }
        tmpXElement.addChild(new XElement("TRSTYP", tmpMap.get("trstyp")));//业务类型编码
        tmpXElement.addChild(new XElement("TRSCAT", tmpMap.get("trscat")));//业务种类编码
        tmpXElement.addChild(new XElement("RMKTXT", p_atsDetail.purpose));//附言
        if (p_atsDetail.isVirtual) {
            if (StringHelper.hasAnyChar(p_atsDetail.virtualNo)) {
                tmpXElement.addChild(new XElement("RSV30Z", p_atsDetail.virtualNo));//保留字 30
            } else {
                retDetail.respCode = "0";
                retDetail.respInfo = "VirtualNo节点中虚拟户编号为空，请检查报文";
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = "E1301";
                return retDetail;
            }
        } else {
            tmpXElement.addChild(new XElement("RSV30Z", ""));//保留字 30
        }
        nodeAnalysis(p_atsDetail.srcXElement, tmpXElement, getCharset());

        xmlWriter.writeXElement(tmpXElement);

        xmlWriter.writeEndDocument();//写入报文完成
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());//发送银行
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            //解析银行返回
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                    boolean hasNodeNTQPAYRQZ = tmpBkReader.read("/CMBSDKPGK/NTOPRRTNZ");
                    if (tmpRetCode.equals("0") && hasNodeNTQPAYRQZ) {
                        retDetail.respCode = "0";
                        String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("REQSTS");
                        if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                            retDetail.transState = tmpBkReader.readedXElement.getSingleText("REQSTS");
                        } else {
                            retDetail.transState = tmpRetCode + "+" + tmpBkReader.readedXElement.getSingleText("ERRCOD");
                        }
                        String retSQRNBR = tmpBkReader.readedXElement.getSingleText("SQRNBR");
                        if (!tmpSQRNBR.equals(retSQRNBR)) {
                            throw new Exception("银行返回的支付流水号" + retSQRNBR + "与提交支付流水号" + tmpSQRNBR + "不符");
                        }
                        retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        retDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ERRCOD");
                        retDetail.respInfo = tmpBkReader.readedXElement.getSingleText("ERRTXT");
                    } else {
                        retDetail.respInfo = tmpRetMsg;
                        retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        if (!tmpRetCode.equals("-9") && !hasNodeNTQPAYRQZ) {
                            retDetail.respCode = "0";
                            retDetail.payInfoCode = tmpRetCode;
                            retDetail.transState = tmpRetCode;
                        } else {
                            retDetail.respCode = "-1";
                        }
                    }
                    if (tmpStrRet[1].contains("通讯故障") || tmpStrRet[1].contains("FBCM176"))//FBCM176 通讯故障
                    {
                        retDetail.respCode = "-1";
                        retDetail.transState = "Unknow";
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = "无/CMBSDKPGK/INFO/RETCOD节点";
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpSbMsg.toString();
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    /**
     * 3.6	直接支付
     * <p>
     * 单笔合批支付
     */
    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        if (getBankConfig().getValueAsBool("useOldSglPay")) {
            return d_1908BAT_SglBatPay_Old(p_req1908BAT);
        } else {
            return d_1908BAT_SglBatPay_New(p_req1908BAT);
        }
    }

    public RetAtsSingleBat d_1908BAT_SglBatPay_New(ReqSingleBat p_req1908BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1908BAT);
        try {
            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "DCPAYMNT";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, tmpBnkHeader);

            xmlWriter.writeStartElement("SDKPAYRQX");
            xmlWriter.writeElementString("BUSCOD", "N02031");
            xmlWriter.writeElementClosed("BUSMOD");
            xmlWriter.writeElementClosed("MODALS");
            xmlWriter.writeEndElement();

            while (p_req1908BAT.readRecord()) {
                ReqPayRecDetail tmpDetail = p_req1908BAT.readedDetail;
                XElement tmpXElement = convertPayRecDetailToBankXElement(tmpDetail);
                xmlWriter.writeXElement(tmpXElement);
            }

            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                WriteBankLogStep3(tmpStrRet[1]);

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    retAts.batRespInfo = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");

                    if (tmpRetCode != null && "0".equals(tmpRetCode)) {
                        retAts.batRespCode = "0";
                        retAts.batTransState = tmpRetCode;
                        retAts.batPayInfoCode = tmpRetCode;

                        while (tmpBkReader.read("/CMBSDKPGK/NTQPAYRQZ")) {
                            RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
                            XElement tmpRetNode = tmpBkReader.readedXElement;

                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpRetNode.getSingleTextNotNull("ERRTXT");
                            tmpRetDetail.reqSeqID = tmpRetNode.getSingleText("YURREF");


                            String tmpRTNFLG = tmpRetNode.getSingleText("RTNFLG");
                            if (StringHelper.hasAnyChar(tmpRTNFLG)) {
                                tmpRetDetail.transState = tmpRetNode.getSingleText("REQSTS") + "+" + tmpRTNFLG;
                            } else {
                                tmpRetDetail.transState = tmpRetNode.getSingleText("REQSTS");
                            }
                            if (tmpRetDetail.respInfo.contains("通讯故障") || tmpRetDetail.respInfo.contains("FBCM176"))//FBCM176 通讯故障
                            {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.transState = "Unknow";
                            }

                            tmpRetDetail.payInfoCode = tmpRetNode.getSingleText("ERRCOD");

                            retAts.writeRetDetail(tmpRetDetail);
                        }
                    } else if (tmpRetCode != null) {
                        //-9和-1时，表示交易可疑，请查询支付结果。
                        if (tmpRetCode.equals("-9") || tmpRetCode.equals("-1")) {
                            retAts.batRespCode = "-1";
                        } else {
                            retAts.batRespCode = "0";
                        }
                        if (StringHelper.hasAnyChar(retAts.batRespInfo)) {
                            if (retAts.batRespInfo.lastIndexOf(":") > retAts.batRespInfo.lastIndexOf("SDK") && retAts.batRespInfo.lastIndexOf("SDK") > -1) {
                                retAts.batPayInfoCode = retAts.batRespInfo.substring(retAts.batRespInfo.lastIndexOf("SDK"), retAts.batRespInfo.lastIndexOf(":"));
                            } else {
                                retAts.batPayInfoCode = retAts.batRespInfo;
                            }
                        }
                        retAts.batTransState = tmpRetCode + "+" + retAts.batPayInfoCode;
                    }
                } else {
                    retAts.batRespCode = "-1";
                    retAts.batRespInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                retAts.batRespCode = "0";
                retAts.batRespInfo = tmpStrRet[1];
                retAts.reqBatchNO = p_req1908BAT.reqBatchNO;
                retAts.batTransState = PaymentState.FAIL_Payment;
                retAts.batPayInfoCode = tmpStrRet[0];
                retAts.batBizState = tmpStrRet[0];
            } else {
                retAts.batRespCode = "-1";
                retAts.batRespInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            retAts.batRespCode = "-1";
            retAts.batRespInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }

    public RetAtsSingleBat d_1908BAT_SglBatPay_Old(ReqSingleBat p_req1908BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1908BAT);

        try {
            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "Payment";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, tmpBnkHeader);

            xmlWriter.writeStartElement("SDKPAYRQX");
            String busCod = getBankConfig().getValueAsString("oldSglPayDefaultBusCod");
            busCod = StringHelper.hasAnyChar(busCod) ? busCod : "N02030";
            xmlWriter.writeElementString("BUSCOD", busCod);
            xmlWriter.writeElementString("BUSMOD", "00001");
            xmlWriter.writeElementString("MODALS", "");
            xmlWriter.writeEndElement();

            while (p_req1908BAT.readRecord()) {
                ReqPayRecDetail tmpDetail = p_req1908BAT.readedDetail;

                XElement tmpXElement = buildPaymentDt(tmpDetail);

                xmlWriter.writeXElement(tmpXElement);
            }

            xmlWriter.writeEndDocument();

            //WriteBankLogStep2(xmlWriter.toXmlString());

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                WriteBankLogStep3(tmpStrRet[1]);

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    retAts.batRespInfo = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");

                    if (tmpRetCode != null && "0".equals(tmpRetCode)) {
                        retAts.batRespCode = "0";
                        retAts.batTransState = tmpRetCode;
                        retAts.batPayInfoCode = tmpRetCode;

                        while (tmpBkReader.read("/CMBSDKPGK/NTQPAYRQZ")) {
                            RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
                            XElement tmpRetNode = tmpBkReader.readedXElement;

                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpRetNode.getSingleTextNotNull("ERRTXT");
                            tmpRetDetail.reqSeqID = tmpRetNode.getSingleText("YURREF");


                            String tmpRTNFLG = tmpRetNode.getSingleText("RTNFLG");
                            if (StringHelper.hasAnyChar(tmpRTNFLG)) {
                                tmpRetDetail.transState = tmpRetNode.getSingleText("REQSTS") + "+" + tmpRTNFLG;
                            } else {
                                tmpRetDetail.transState = tmpRetNode.getSingleText("REQSTS");
                            }
                            if (tmpRetDetail.respInfo.contains("通讯故障") || tmpRetDetail.respInfo.contains("FBCM176"))//FBCM176 通讯故障
                            {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.transState = "Unknow";
                            }

                            tmpRetDetail.payInfoCode = tmpRetNode.getSingleText("ERRCOD");

                            retAts.writeRetDetail(tmpRetDetail);
                        }
                    } else if (tmpRetCode != null) {
                        //-9和-1时，表示交易可疑，请查询支付结果。
                        if (tmpRetCode.equals("-9") || tmpRetCode.equals("-1")) {
                            retAts.batRespCode = "-1";
                        } else {
                            retAts.batRespCode = "0";
                        }
                        if (StringHelper.hasAnyChar(retAts.batRespInfo)) {
                            if (retAts.batRespInfo.lastIndexOf(":") > retAts.batRespInfo.lastIndexOf("SDK") && retAts.batRespInfo.lastIndexOf("SDK") > -1) {
                                retAts.batPayInfoCode = retAts.batRespInfo.substring(retAts.batRespInfo.lastIndexOf("SDK"), retAts.batRespInfo.lastIndexOf(":"));
                            } else {
                                retAts.batPayInfoCode = retAts.batRespInfo;
                            }
                        }
                        retAts.batTransState = tmpRetCode + "+" + retAts.batPayInfoCode;
                    }
                } else {
                    retAts.batRespCode = "-1";
                    retAts.batRespInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                retAts.batRespCode = "0";
                retAts.batRespInfo = tmpStrRet[1];
                retAts.reqBatchNO = p_req1908BAT.reqBatchNO;
                retAts.batTransState = PaymentState.FAIL_Payment;
                retAts.batPayInfoCode = tmpStrRet[0];
                retAts.batBizState = tmpStrRet[0];
            } else {
                retAts.batRespCode = "-1";
                retAts.batRespInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            retAts.batRespCode = "-1";
            retAts.batRespInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }

    private XElement convertPayRecDetailToBankXElement(ReqPayRecDetail p_atsDetail) throws Exception {
        //需要进行对账码拼接以及节点解析，采用XElement进行处理
        XElement tmpXElement = new XElement("DCOPDPAYX", "");
        tmpXElement.addChild(new XElement("YURREF", p_atsDetail.askNumber));
        tmpXElement.addChild(new XElement("EPTDAT", ""));//Format.Date8Format.format(p_atsDetail.getPayDateTime())
        tmpXElement.addChild(new XElement("EPTTIM", ""));//p_req1908.payDetail.payTime
        tmpXElement.addChild(new XElement("DBTACC", p_atsDetail.payAct));
        tmpXElement.addChild(new XElement("DBTBBK", p_atsDetail.payArea));
        tmpXElement.addChild(new XElement("TRSAMT", p_atsDetail.payAmount));
        tmpXElement.addChild(new XElement("CCYNBR", convertCurToBank(p_atsDetail.payCur)));
        //N：普通		F：快速
        if (p_atsDetail.paySpd != null && p_atsDetail.paySpd.equals("1")) {
            tmpXElement.addChild(new XElement("STLCHN", "F"));
        } else {
            tmpXElement.addChild(new XElement("STLCHN", "N"));
        }
        String purpose = p_atsDetail.purpose;
        if (StringHelper.hasAnyChar(purpose) && purpose.getBytes(getCharset()).length > 62) {
            purpose = new String(purpose.getBytes(getCharset()), 0, 62);
        }
        if (StringHelper.isNullOrEmpty(purpose)) {
            purpose = "无";
        }
        tmpXElement.addChild(new XElement("NUSAGE", purpose));
        tmpXElement.addChild(new XElement("BUSNAR", p_atsDetail.abstractATS));
        tmpXElement.addChild(new XElement("CRTACC", p_atsDetail.recAct));
        tmpXElement.addChild(new XElement("CRTNAM", ""));
        tmpXElement.addChild(new XElement("LRVEAN", p_atsDetail.recName));
        /* 逻辑注释，招行答复可全部替换为长户名
         * if (p_atsDetail.recName.getBytes(getCharset()).length > 62) {
        	tmpXElement.addChild(new XElement("CRTNAM", ""));
        	tmpXElement.addChild(new XElement("LRVEAN", p_atsDetail.recName));
        } else {
        	tmpXElement.addChild(new XElement("CRTNAM", p_atsDetail.recName));
        	tmpXElement.addChild(new XElement("LRVEAN", ""));
        }*/

        //BRDNBR 人行自动支付收方联行号
        //BNKFLG 系统内外标志 Y：招行；N：非招行；

        if (p_atsDetail.sameBnk != null && p_atsDetail.sameBnk.equals("1")) {
            tmpXElement.addChild(new XElement("BRDNBR", ""));
            tmpXElement.addChild(new XElement("BNKFLG", "Y"));
            //同行对私付款
            if (getBankConfig().getValueAsBool("sameIsPrivatePay") && "1".equals(p_atsDetail.isPrivate) && p_atsDetail.recAct.length() == 12) {
                //收方开户行
                if (!StringHelper.isNullOrEmpty(p_atsDetail.cnapsName)) {
                    tmpXElement.addChild(new XElement("CRTBNK", p_atsDetail.cnapsName));
                } else {
                    tmpXElement.addChild(new XElement("CRTBNK", p_atsDetail.recBankLocation));
                }
                String[] tmpPC = p_atsDetail.getOppAreaName2().split("_");
                String provinceAndCity = tmpXElement.getSingleText("CRTBNK");
                if (tmpPC != null && tmpPC.length > 1) {
                    provinceAndCity = tmpPC[0] + tmpPC[1];
                }
                tmpXElement.addChild(new XElement("CTYCOD", ""));//城市代码
                tmpXElement.addChild(new XElement("CRTADR", provinceAndCity));//收方行地址
            } else {
                tmpXElement.addChild(new XElement("CRTBNK", ""));
                tmpXElement.addChild(new XElement("CTYCOD", ""));//城市代码 行内支付填写，为空则不支持收方识别功能。
                tmpXElement.addChild(new XElement("CRTADR", ""));//收方行地址 跨行支付（BNKFLG=N）必填
            }
        } else {
            if (getBankConfig().getValueAsBool("disableSingleCnapsCode")) {
                tmpXElement.addChild(new XElement("BRDNBR", ""));
            } else {
                tmpXElement.addChild(new XElement("BRDNBR", p_atsDetail.cnapsCode));
            }
            tmpXElement.addChild(new XElement("BNKFLG", "N"));

            if (!StringHelper.isNullOrEmpty(p_atsDetail.cnapsName)) {
                tmpXElement.addChild(new XElement("CRTBNK", p_atsDetail.cnapsName));
            } else {
                tmpXElement.addChild(new XElement("CRTBNK", p_atsDetail.recBankLocation));
            }
            String[] tmpPC = p_atsDetail.getOppAreaName2().split("_");
            String provinceAndCity = tmpXElement.getSingleText("CRTBNK");
            if (tmpPC != null && tmpPC.length > 1) {
                provinceAndCity = tmpPC[0] + tmpPC[1];
            }
            if (tmpPC != null && tmpPC.length == 1) {
                provinceAndCity = tmpPC[0] + tmpPC[0];
            }
            tmpXElement.addChild(new XElement("CTYCOD", ""));//城市代码 行内支付填写，为空则不支持收方识别功能。
            //收方行地址 跨行支付（BNKFLG=N）必填
            tmpXElement.addChild(new XElement("CRTADR", provinceAndCity));
        }
        tmpXElement.addChild(new XElement("CRTFLG", getBankConfig().getValueAsString("crtflg")));//收方信息不检查标志
        tmpXElement.addChild(new XElement("NTFCH1", ""));
        tmpXElement.addChild(new XElement("NTFCH2", ""));
        tmpXElement.addChild(new XElement("CRTSQN", ""));
        tmpXElement.addChild(new XElement("TRSTYP", "100001"));
        tmpXElement.addChild(new XElement("RCVCHK", "1"));
        tmpXElement.addChild(new XElement("RSV28Z", ""));
        nodeAnalysis(p_atsDetail.srcXElement, tmpXElement, getCharset());
        return tmpXElement;
    }

    /**
     * 4.2.直接代发代扣 AgentRequest
     *
     * @param p_req9108
     * @return
     * @throws Exception
     */
    public RetAtsSglDetail d_1908_AgentRequest(ReqSingle p_req9108) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;

        try {
            String tmpBUSCOD = "N03020";
            String tmpBUSMOD = getBankConfig().getMapValueByKey("busmod" + tmpBUSCOD, p_req9108.singleDetail.purpose);
            String tmpTrstypCode = getBankConfig().getMapValueByKey("ctrstypCode" + tmpBUSCOD, p_req9108.singleDetail.purpose);
            String tmpTrstypName = getBankConfig().getMapValueByKey("ctrstypName" + tmpBUSCOD, p_req9108.singleDetail.purpose);

            boolean isChecked = true;
            String tmpCheckMsg = "";
            if (StringHelper.isNullOrEmpty(tmpBUSMOD)) {
                isChecked = false;
                tmpCheckMsg = "未取到" + tmpBUSCOD + "的业务模式设置";
            }
            if (StringHelper.isNullOrEmpty(tmpTrstypCode)) {
                isChecked = false;
                tmpCheckMsg = "未取到" + tmpBUSCOD + "的交易代码设置";
            }
            if (StringHelper.isNullOrEmpty(tmpTrstypName)) {
                isChecked = false;
                tmpCheckMsg = tmpCheckMsg + "未取到" + tmpBUSCOD + "交易代码名称设置！";
            }
            if (!isChecked) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpCheckMsg;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = "E9981";
                return tmpRetDetail;
            }

            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "AgentRequest";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, tmpBnkHeader);
            xmlWriter.writeStartElement("SDKATSRQX");
            xmlWriter.writeElementString("BUSCOD", tmpBUSCOD);
            xmlWriter.writeElementString("BUSMOD", tmpBUSMOD);
            xmlWriter.writeElementClosed("MODALS");
            xmlWriter.writeElementString("C_TRSTYP", tmpTrstypName);
            xmlWriter.writeElementString("TRSTYP", tmpTrstypCode);
            xmlWriter.writeElementClosed("EPTDAT");
            xmlWriter.writeElementString("DBTACC", p_req9108.singleDetail.payAct);
            xmlWriter.writeElementString("BBKNBR", p_req9108.singleDetail.payArea);
            xmlWriter.writeElementClosed("BANKAREA");
            xmlWriter.writeElementString("SUM", p_req9108.singleDetail.payAmount);
            xmlWriter.writeElementString("TOTAL", "1");
            xmlWriter.writeElementString("CCYNBR", convertCurToBank(p_req9108.singleDetail.payCur));
            xmlWriter.writeElementClosed("CURRENCY");
            xmlWriter.writeElementString("YURREF", p_req9108.singleDetail.askNumber);
            String bkMEMO = StringHelper.joinNotEmpty("-", p_req9108.singleDetail.abstractATS, p_req9108.singleDetail.purpose);
            bkMEMO = StringHelper.subStringByByte(bkMEMO, getCharset(), 42);
            xmlWriter.writeElementString("MEMO", bkMEMO);
            /*直连经办网银审批标志    为 Y 时必须使用有审批岗的模式；不为 Y 时，必须使用无审批岗的模式。*/
         /*   String grtFlag = getBankConfig().getValueAsString("grtFlag");
            if (grtFlag==null||"".equals(grtFlag)) {
                grtFlag = "N";
            }
            xmlWriter.writeElementString("GRTFLG", grtFlag);*/

            xmlWriter.writeEndElement();

            //需要进行对账码拼接以及节点解析，采用XElement进行处理
            XElement tmpXElement = new XElement("SDKATDRQX", "");
            tmpXElement.addChild(new XElement("ACCNBR", p_req9108.singleDetail.recAct));
            tmpXElement.addChild(new XElement("CLTNAM", p_req9108.singleDetail.recName));
            tmpXElement.addChild(new XElement("TRSAMT", p_req9108.singleDetail.payAmount));
            if (p_req9108.singleDetail.sameBnk.equals("1")) {
                tmpXElement.addChild(new XElement("BNKFLG", "Y"));
                tmpXElement.addChild(new XElement("EACBNK", ""));
                tmpXElement.addChild(new XElement("EACCTY", ""));
            } else {
                tmpXElement.addChild(new XElement("BNKFLG", "N"));
                tmpXElement.addChild(new XElement("EACBNK", p_req9108.singleDetail.getOppBankLocation()));
                tmpXElement.addChild(new XElement("EACCTY", p_req9108.singleDetail.getOppStandardArea()));
            }
            tmpXElement.addChild(new XElement("TRSDSP", ""));
            nodeAnalysis(p_req9108.singleDetail.srcXElement, tmpXElement, getCharset());
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (!StringHelper.isNullOrEmpty(tmpRetCode) && !tmpRetCode.equals("-9")) {
                        tmpRetDetail.respCode = "0";
                        String tmpRSV50Z = tmpBkReader.getFirstText("/CMBSDKPGK/NTREQNBRY/RSV50Z");
                        if (tmpRSV50Z != null && tmpRSV50Z.length() > 0) {
//                            tmpRetDetail.transState = tmpRetCode + "+" + tmpRSV50Z;
//                            tmpRetDetail.payInfoCode = tmpRSV50Z;

                            // 当招行返回支付中时立刻发起支付状态查询
                            if ("BNK".equals(tmpRSV50Z)) {
                                long realSleepTime = getBankConfig().getValueAsInt("realSleepTime");
                                Thread.sleep(realSleepTime * 1000);

                                if (getBankConfig().getValueAsBool("UseNewQrySglRec")) {
                                    tmpBnkHeader.FUNNAM = "NTAGCINN";

                                    Calendar tmpBGNDAT = Calendar.getInstance();
                                    tmpBGNDAT.setTime(p_req9108.singleDetail.getPayDateTime());
                                    tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

                                    Calendar tmpENDDAT = Calendar.getInstance();
                                    tmpENDDAT.setTime(p_req9108.singleDetail.getPayDateTime());
                                    tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

                                    xmlWriter = new XmlTextWriter();
                                    writeCommonHeader(xmlWriter, tmpBnkHeader);
                                    xmlWriter.writeStartElement("NTAGCINNY1");
                                    xmlWriter.writeElementString("BUSCOD", tmpBUSCOD);
                                    xmlWriter.writeElementString("BUSMOD", tmpBUSMOD);
                                    xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
                                    xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));
                                    xmlWriter.writeElementString("DATFLG", "A");
                                    xmlWriter.writeElementClosed("RSV50Z");
                                    xmlWriter.writeEndDocument();

                                    boolean isFinished = false;
                                    String tmpREQNBR = "";
                                    String tmpStrYURREF = "";
                                    String tmpStrBatchREQSTA = "";
                                    String tmpStrBatchRTNFLG = "";
                                    try {
                                        String[] tmpStrQryRet = sendToBank(xmlWriter.toXmlString());
                                        if (tmpStrQryRet[0].length() == 0) {
                                            tmpBkReader = loadBankRespXmlReader(tmpStrQryRet[1], tmpSbMsg);
                                            if (tmpBnkHeader != null) {
                                                tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                                                tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                                                if (tmpRetCode != null && tmpRetCode.equals("0")) {
                                                    boolean hasMatched = false;
                                                    while (tmpBkReader.read("/CMBSDKPGK/NTAGCINQZ")) {
                                                        String tmpStrC_REQSTA = tmpBkReader.readedXElement.getSingleText("C_REQSTA");
                                                        String tmpStrREQSTA = tmpBkReader.readedXElement.getSingleText("REQSTA");//业务请求状态
                                                        //业务处理结果//当REQSTA=FIN且RTNFLG=S需检查RSV62Z第一位是否为’P’，是表示部分成功，否则表示全部成功。
                                                        String tmpStrRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                                                        String tmpStrSUCAMT = tmpBkReader.readedXElement.getSingleText("SUCAMT");
                                                        String tmpStrSUCNUM = tmpBkReader.readedXElement.getSingleText("SUCNUM");
                                                        String tmpStrERRDSP = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                                                        tmpStrYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                                                        tmpREQNBR = tmpBkReader.readedXElement.getSingleText("REQNBR");
                                                        if (tmpStrYURREF != null && p_req9108.singleDetail.askNumber.equals(tmpStrYURREF)) {
                                                            hasMatched = true;
                                                            tmpStrBatchREQSTA = tmpStrREQSTA;
                                                            tmpStrBatchRTNFLG = tmpStrRTNFLG;
                                                            tmpRetDetail.reqSeqID = tmpStrYURREF;
                                                            if (tmpStrERRDSP != null && tmpStrERRDSP.length() > 32) {
                                                                tmpStrERRDSP = tmpStrERRDSP.substring(0, 33);
                                                            }
                                                            if (tmpStrREQSTA.equals("FIN") && tmpStrRTNFLG.equals("F") && StringHelper.isNullOrEmpty(tmpREQNBR)) {
                                                                float tmpSUCAMT = Float.parseFloat(tmpStrSUCAMT);
                                                                float tmpSUCNUM = Float.parseFloat(tmpStrSUCNUM);
                                                                if (tmpSUCAMT == 0 && tmpSUCNUM == 0) {
                                                                    tmpRetDetail.respCode = "0";
                                                                    tmpRetDetail.respInfo = tmpStrERRDSP;
                                                                    tmpRetDetail.transState = tmpStrREQSTA + "+" + tmpStrRTNFLG;
                                                                    tmpRetDetail.payInfoCode = tmpStrERRDSP;
                                                                    isFinished = true;
                                                                } else {
                                                                    tmpRetDetail.respCode = "-1";
                                                                    tmpRetDetail.respInfo = "成功笔数或成功金额不符合预期";
                                                                }
                                                            } else if (tmpStrREQSTA != null && !tmpStrREQSTA.equals("FIN")) {
                                                                tmpRetDetail.respCode = "0";
                                                                tmpRetDetail.respInfo = tmpStrC_REQSTA;
                                                                tmpRetDetail.transState = tmpStrREQSTA;
                                                                tmpRetDetail.payInfoCode = tmpStrREQSTA;
                                                                isFinished = true;
                                                            } else if (StringHelper.isNullOrEmpty(tmpStrREQSTA)) {
                                                                tmpRetDetail.respCode = "-1";
                                                                tmpRetDetail.respInfo = "批次的业务请求状态为空";
                                                            }
                                                        }
                                                    }
                                                    if (hasMatched == false) {
                                                        if (getBankConfig().getValueAsString("canBeFailed").contains(p_req9108.singleDetail.askNumber)) {
                                                            tmpRetDetail.respCode = "0";
                                                            tmpRetDetail.transState = "PaymentFailed";
                                                            tmpRetDetail.payInfoCode = "";
                                                            tmpRetDetail.respInfo = tmpRetMsg;
                                                            tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
                                                            isFinished = true;
                                                        } else {
                                                            tmpRetDetail.respCode = "-1";
                                                            tmpRetDetail.respInfo = "银行未返回该批次相关信息";
                                                        }
                                                    }
                                                } else {
                                                    tmpRetDetail.respCode = "-1";
                                                    tmpRetDetail.respInfo = tmpRetMsg;
                                                }
                                            }/* else {
                                                tmpRetDetail.respCode = "-1";
                                                tmpRetDetail.respInfo = tmpSbMsg.toString();
                                            }*/
                                        } else {
                                            tmpRetDetail.respCode = "-1";
                                            tmpRetDetail.respInfo = tmpStrQryRet[1];
                                        }
                                    } catch (Exception e) {
                                        tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = e.getMessage();
                                        e.printStackTrace();
                                    }

                                    if (isFinished || "-1".equals(tmpRetDetail.respCode)) {
                                        return tmpRetDetail;
                                    }

                                    //查明细
                                    tmpBnkHeader.FUNNAM = "GetAgentDetail";
                                    xmlWriter = new XmlTextWriter();
                                    writeCommonHeader(xmlWriter, tmpBnkHeader);
                                    xmlWriter.writeStartElement("SDKATDQYX");
                                    xmlWriter.writeElementString("REQNBR", tmpREQNBR);
                                    xmlWriter.writeEndDocument();

                                    try {
                                        tmpStrRet = sendToBank(xmlWriter.toXmlString());
                                        if (tmpStrRet[0].length() == 0) {
                                            tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                                            if (tmpBkReader != null) {
                                                tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                                                tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                                                if (tmpRetCode != null && tmpRetCode.equals("0")) {
                                                    if (tmpBkReader.read("/CMBSDKPGK/NTQATDQYZ")) {
                                                        tmpRetDetail.respCode = "0";
                                                        tmpRetDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TRSAMT");
                                                        tmpRetDetail.reqSeqID = tmpStrYURREF;
                                                        tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpBkReader.readedXElement.getSingleText("STSCOD");
                                                        if (tmpStrBatchRTNFLG.equals("F") && tmpBkReader.readedXElement.getSingleText("STSCOD").equals("I")) {
                                                            tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpStrBatchRTNFLG + "+" + tmpBkReader.readedXElement.getSingleText("STSCOD");
                                                        }
                                                        tmpRetDetail.respInfo = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                                                        tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                                                        if (tmpRetDetail.payInfoCode != null && tmpRetDetail.payInfoCode.length() > 32) {
                                                            tmpRetDetail.payInfoCode = tmpRetDetail.payInfoCode.substring(0, 33);
                                                        }
                                                    }
                                                } else {
                                                    tmpRetDetail.respCode = "-1";
                                                    tmpRetDetail.respInfo = tmpRetMsg;
                                                }
                                            } else {
                                                tmpRetDetail.respCode = "-1";
                                                tmpRetDetail.respInfo = tmpSbMsg.toString();
                                            }
                                        } else {
                                            tmpRetDetail.respCode = "-1";
                                            tmpRetDetail.respInfo = tmpStrRet[1];
                                        }
                                    } catch (Exception e) {
                                        tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = e.getMessage();
                                        e.printStackTrace();
                                    }
                                    return tmpRetDetail;
                                }
                            }
                        } else {
                            tmpRetDetail.transState = tmpRetCode;
                            tmpRetDetail.payInfoCode = tmpRetCode;
                        }
                        tmpRetDetail.respInfo = tmpRetMsg;
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpRetMsg;
                    }
                    if (tmpStrRet[1].contains("通讯故障") || tmpStrRet[1].contains("FBCM176")) {//FBCM176 通讯故障
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.transState = "Unknow";
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req9108.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Batch;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }

        } catch (Exception e) {
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.toString();
            e.printStackTrace();
        }
        return tmpRetDetail;
    }

    /**
     * 3.6.直接支付 DCPAYMNT
     *
     * @param p_req1908
     * @return
     * @throws Exception
     */
    private RetAtsSglDetail d_190802_DCPAYMNT(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        CMB01Header tmpBnkHeader = new CMB01Header();
        tmpBnkHeader.FUNNAM = "DCPAYMNT";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入通用的头部节点
        //Date tmpDateNow = new Date();
        writeCommonHeader(xmlWriter, tmpBnkHeader);

        xmlWriter.writeStartElement("SDKPAYRQX");
        xmlWriter.writeElementString("BUSCOD", "N02031");
        //xmlWriter.writeElementString("BUSMOD", "00001");
        //xmlWriter.writeElementClosed("MODALS");
        xmlWriter.writeEndElement();
        XElement tmpXElement = convertPayRecDetailToBankXElement(p_req1908.singleDetail);
        xmlWriter.writeXElement(tmpXElement);

        xmlWriter.writeEndDocument();//写入报文完成
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());//发送银行
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            //解析银行返回
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                    boolean hasNodeNTQPAYRQZ = tmpBkReader.read("/CMBSDKPGK/NTQPAYRQZ");
                    if (tmpRetCode.equals("0") && hasNodeNTQPAYRQZ) {
                        retDetail.respCode = "0";
                        String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                        if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                            retDetail.transState = tmpBkReader.readedXElement.getSingleText("REQSTS") + "+" + tmpRTNFLG;
                        } else {
                            retDetail.transState = tmpBkReader.readedXElement.getSingleText("REQSTS");
                        }
                        retDetail.reqSeqID = tmpBkReader.readedXElement.getSingleText("YURREF");
                        if (!retDetail.reqSeqID.equals(p_req1908.singleDetail.askNumber)) {
                            throw new Exception("银行返回的支付流水号" + retDetail.reqSeqID + "与提交支付流水号" + p_req1908.singleDetail.askNumber + "不符");
                        }
                        retDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ERRCOD");
                        retDetail.respInfo = tmpBkReader.readedXElement.getSingleText("ERRTXT");
                        retDetail.outTransID = tmpBkReader.readedXElement.getSingleText("REQNBR");
                    } else {
                        retDetail.respInfo = tmpRetMsg;
                        retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        if (!tmpRetCode.equals("-9") && !hasNodeNTQPAYRQZ) {
                            retDetail.respCode = "0";
                            retDetail.payInfoCode = tmpRetCode;
                            retDetail.transState = tmpRetCode;
                        } else {
                            retDetail.respCode = "-1";
                        }
                    }
                    if (tmpStrRet[1].contains("通讯故障") || tmpStrRet[1].contains("FBCM176"))//FBCM176 通讯故障
                    {
                        retDetail.respCode = "-1";
                        retDetail.transState = "Unknow";
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = "无/CMBSDKPGK/INFO/RETCOD节点";
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpSbMsg.toString();
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    //190802对外支付
    private RetAtsSglDetail d_190802_Payment(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        CMB01Header tmpBnkHeader = new CMB01Header();
        tmpBnkHeader.FUNNAM = "Payment";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        //写入通用的头部节点
        //Date tmpDateNow = new Date();
        writeCommonHeader(xmlWriter, tmpBnkHeader);

        xmlWriter.writeStartElement("SDKPAYRQX");
        String busCod = getBankConfig().getValueAsString("oldSglPayDefaultBusCod");
        busCod = StringHelper.hasAnyChar(busCod) ? busCod : "N02030";
        xmlWriter.writeElementString("BUSCOD", busCod);
        xmlWriter.writeElementString("BUSMOD", "00001");
        xmlWriter.writeElementClosed("MODALS");
        xmlWriter.writeEndElement();
        XElement tmpXElement = buildPaymentDt(p_req1908.singleDetail);
        xmlWriter.writeXElement(tmpXElement);

        xmlWriter.writeEndDocument();//写入报文完成
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());//发送银行
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            //解析银行返回
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                    boolean hasNodeNTQPAYRQZ = tmpBkReader.read("/CMBSDKPGK/NTQPAYRQZ");
                    if (tmpRetCode.equals("0") && hasNodeNTQPAYRQZ) {
                        retDetail.respCode = "0";
                        String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                        if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                            retDetail.transState = tmpBkReader.readedXElement.getSingleText("REQSTS") + "+" + tmpRTNFLG;
                        } else {
                            retDetail.transState = tmpBkReader.readedXElement.getSingleText("REQSTS");
                        }
                        retDetail.reqSeqID = tmpBkReader.readedXElement.getSingleText("YURREF");
                        if (!retDetail.reqSeqID.equals(p_req1908.singleDetail.askNumber)) {
                            throw new Exception("银行返回的支付流水号" + retDetail.reqSeqID + "与提交支付流水号" + p_req1908.singleDetail.askNumber + "不符");
                        }
                        retDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ERRCOD");
                        retDetail.respInfo = tmpBkReader.readedXElement.getSingleText("ERRTXT");
                        retDetail.outTransID = tmpBkReader.readedXElement.getSingleText("REQNBR");
                    } else {
                        retDetail.respInfo = tmpRetMsg;
                        retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        if (!tmpRetCode.equals("-9") && !hasNodeNTQPAYRQZ) {
                            retDetail.respCode = "0";
                            retDetail.payInfoCode = tmpRetCode;
                            retDetail.transState = tmpRetCode;
                        } else {
                            retDetail.respCode = "-1";
                        }
                    }
                    if (tmpStrRet[1].contains("通讯故障") || tmpStrRet[1].contains("FBCM176"))//FBCM176 通讯故障
                    {
                        retDetail.respCode = "-1";
                        retDetail.transState = "Unknow";
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = "无/CMBSDKPGK/INFO/RETCOD节点";
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpSbMsg.toString();
            }
        } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
            retDetail.respCode = "0";
            retDetail.respInfo = tmpStrRet[1];
            retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            retDetail.transState = PaymentState.FAIL_Payment;
            retDetail.payInfoCode = tmpStrRet[0];
        } else {
            retDetail.respCode = "-1";
            retDetail.respInfo = tmpStrRet[1];
        }
        return retDetail;
    }

    /**
     * 招行Payment接口，组装单笔支付节点，单笔和单笔合批复用
     *
     * @throws Exception
     */
    private XElement buildPaymentDt(ReqPayRecDetail pDetail) throws Exception {
        //需要进行对账码拼接以及节点解析，采用XElement进行处理
        XElement tmpXElement = new XElement("SDKPAYDTX", "");

        tmpXElement.addChild(new XElement("YURREF", pDetail.askNumber));
        tmpXElement.addChild(new XElement("EPTDAT", ""));//Format.Date8Format.format(p_atsDetail.getPayDateTime())
        tmpXElement.addChild(new XElement("EPTTIM", ""));//p_req1908.payDetail.payTime
        tmpXElement.addChild(new XElement("DBTACC", pDetail.payAct));
        tmpXElement.addChild(new XElement("DBTBBK", pDetail.payArea));
        tmpXElement.addChild(new XElement("C_DBTBBK", ""));
        tmpXElement.addChild(new XElement("TRSAMT", pDetail.payAmount));
        tmpXElement.addChild(new XElement("CCYNBR", convertCurToBank(pDetail.payCur)));
        tmpXElement.addChild(new XElement("C_CCYNBR", ""));
        //N：普通		F：快速
        if (pDetail.paySpd != null && pDetail.paySpd.equals("1")) {
            tmpXElement.addChild(new XElement("STLCHN", "F"));
        } else {
            tmpXElement.addChild(new XElement("STLCHN", "N"));
        }
        tmpXElement.addChild(new XElement("C_STLCHN", ""));

        String purpose = StringHelper.subStringByByte(pDetail.purpose, getCharset(), 62);
        if (StringHelper.isNullOrEmpty(purpose)) {
            purpose = "无";
        }
        tmpXElement.addChild(new XElement("NUSAGE", purpose));
        tmpXElement.addChild(new XElement("BUSNAR", pDetail.abstractATS));
        tmpXElement.addChild(new XElement("CRTACC", pDetail.recAct));
        tmpXElement.addChild(new XElement("CRTNAM", pDetail.recName));
        //BRDNBR 人行自动支付收方联行号
        //BNKFLG 系统内外标志 Y：招行；N：非招行；
        if (pDetail.sameBnk != null && pDetail.sameBnk.equals("1")) {
            //tmpXElement.addChild(new XElement("BRDNBR", ""));
            tmpXElement.addChild(new XElement("BNKFLG", "Y"));
            //tmpXElement.addChild(new XElement("CRTBNK", ""));
        } else {
            tmpXElement.addChild(new XElement("BNKFLG", "N"));
        }
        if (getBankConfig().getValueAsBool("disableSingleCnapsCode")) {
            tmpXElement.addChild(new XElement("BRDNBR", ""));
        } else {
            tmpXElement.addChild(new XElement("BRDNBR", pDetail.cnapsCode));
        }
        if (!StringHelper.isNullOrEmpty(pDetail.cnapsName)) {
            tmpXElement.addChild(new XElement("CRTBNK", pDetail.cnapsName));
        } else {
            tmpXElement.addChild(new XElement("CRTBNK", pDetail.recBankLocation));
        }
        tmpXElement.addChild(new XElement("CTYCODE", ""));
        String[] tmpRecAreaName = pDetail.recAreaName != null ? pDetail.recAreaName.split("_") : new String[]{""};
        if (tmpRecAreaName.length == 2) {
            tmpXElement.addChild(new XElement("CRTPVC", tmpRecAreaName[0]));
            tmpXElement.addChild(new XElement("CRTCTY", tmpRecAreaName[1]));
        } else {
            tmpXElement.addChild(new XElement("CRTPVC", tmpRecAreaName[0]));
            tmpXElement.addChild(new XElement("CRTCTY", tmpRecAreaName[0]));
        }
        tmpXElement.addChild(new XElement("NTFCH1", ""));
        tmpXElement.addChild(new XElement("NTFCH2", ""));
        tmpXElement.addChild(new XElement("CRTSQN", ""));
        tmpXElement.addChild(new XElement("TRSTYP", "100001"));
        tmpXElement.addChild(new XElement("RSV29Z", ""));

        nodeAnalysis(pDetail.srcXElement, tmpXElement, getCharset());
        return tmpXElement;
    }

    /**
     * 单笔付款状态查询
     * @param p_req1944
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        boolean useNoticeQrySglPay = getBankConfig().getValueAsBool("UseNoticeQrySglPay");
        WriteBankLogLn("UseNoticeQrySglPay：" + useNoticeQrySglPay);
        if (useNoticeQrySglPay) {
            RetAtsSingle retFromNtc = d_1944_QrySglPayByNotice(p_req1944);
            if (retFromNtc != null && retFromNtc.retDetail != null && "0".equals(retFromNtc.retDetail.respCode)) {
                WriteBankLogLn("从通知中提取成功");
                return retFromNtc;
            }
        }


        String isSetSleep = getBankConfig().getValueAsString("useSleepGetQuery");
        if ("true".equals(isSetSleep.toLowerCase())) {
            int realSleepTime = getBankConfig().getValueAsInt("QuerySleepTime");
            if (realSleepTime > 0) {
                Date lastSleepGetQuery;
                String keyLastSleep = "lastSleepGetQuery1944";
                synchronized (bankFront.mutex1944) {
                    if (this.bankFront.customObjects.containsKey(keyLastSleep)) {
                        lastSleepGetQuery = (Date) bankFront.customObjects.get(keyLastSleep);
                        long diffMil = DateHelper.getDifferMilSecs(new Date(), lastSleepGetQuery);
                        long needSlpMil = realSleepTime * 1000;
                        long slpMil = needSlpMil - diffMil;
                        if (slpMil > 0) {
                            this.WriteBankLogLn("等待" + slpMil + "毫秒");
                            Thread.sleep(slpMil);
                        }
                        bankFront.putCustomObjects(keyLastSleep, new Date());
                    } else {
                        bankFront.putCustomObjects(keyLastSleep, new Date());
                    }
                }

            }
        }
        if ("190802DCPAY".equals(p_req1944.reqHeader.commandCode)) {
            return d_1944_NTQRYSTY(p_req1944);
        } else if ("190804".equals(p_req1944.reqHeader.commandCode)) {
            return d_1944_NTAGCINN(p_req1944);
        }else if ("190805".equals(p_req1944.reqHeader.commandCode)) {
            if (getBankConfig().getValueAsBool("UseNewQryEbank")) {
                return d_1944_QrySglForNewEBank(p_req1944);
            } else {
                return d_1944_QrySglForEBank(p_req1944);
            }
        } else {
            if (getBankConfig().getValueAsBool("UseNewQrySglPay")) {
            	return d_1944_NTQRYSTY(p_req1944);
            } else {
                return d_1944_QrySglPayOld(p_req1944);
            }
        }
    }

    private RetAtsSingle d_1944_QrySglForNewEBank(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;

        try {
            WriteBankLogLn("开始调用接口:NTQRYEBY");

            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "NTQRYEBY";
            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, tmpBnkHeader);
            xmlWriter.writeStartElement("NTQRYEBYX1");
            xmlWriter.writeElementString("BUSCOD", "N31010");
            xmlWriter.writeElementString("YURREF", p_req1944.askNumber);
//            备注:现场测试招行填写招行固定测试服务器日期时使用,需在config.xml中增加配置节点:<TestDate>20191028</TestDate>
//            Date bgnDate = Format.Date8Format.parse(getBankConfig().getValueAsString("TestDate"));
            Date bgnDate = p_req1944.getBgnDateTime();
            Calendar tmpBGNDAT = Calendar.getInstance();
            tmpBGNDAT.setTime(bgnDate);
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

            Calendar tmpENDDAT = Calendar.getInstance();
            tmpENDDAT.setTime(bgnDate);
            tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

            xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
            xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));
            xmlWriter.writeElementString("RSV50Z", "");
            xmlWriter.writeEndDocument();

            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());

            WriteBankLogLn("'NTQRYEBY'接口调用结束，开始解析");

            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        if (tmpBkReader.read("/CMBSDKPGK/NTWAUEBPZ")) {
                            String tmpYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                            tmpRetAtsDetail.reqSeqID = tmpYURREF;
                            if (!p_req1944.askNumber.equals(tmpYURREF)) {
                                throw new Exception("银行返回的支付流水号" + tmpYURREF + "与查询支付流水号" + p_req1944.askNumber + "不符");
                            }
                            tmpRetAtsDetail.respCode = "0";

                            String reqNbr = tmpBkReader.readedXElement.getSingleText("REQNBR");

                            WriteBankLogLn("开始调用接口:NTEBPINF");


                            tmpBnkHeader = new CMB01Header();
                            tmpBnkHeader.FUNNAM = "NTEBPINF";
                            xmlWriter = new XmlTextWriter();
                            writeCommonHeader(xmlWriter, tmpBnkHeader);
                            xmlWriter.writeStartElement("NTEBPINFX");
                            xmlWriter.writeElementString("REQNBR", reqNbr);
                            xmlWriter.writeElementString("TRXNBR", "");
                            xmlWriter.writeEndDocument();

                            tmpRetBkStr = sendToBank(xmlWriter.toXmlString());

                            WriteBankLogLn("'NTEBPINF'接口调用结束，开始解析");

                            if (tmpRetBkStr[0].length() == 0) {
                                tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                                if (tmpBkReader != null) {
                                    tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                                    tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                                    if ("0".equals(tmpRetCode)) {
                                        if (tmpBkReader.read("/CMBSDKPGK/NTEBPINFZ")) {
                                            tmpYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                                            tmpRetAtsDetail.reqSeqID = tmpYURREF;
                                            if (!p_req1944.askNumber.equals(tmpYURREF)) {
                                                throw new Exception("银行返回的支付流水号" + tmpYURREF + "与查询支付流水号" + p_req1944.askNumber + "不符");
                                            }
                                            tmpRetAtsDetail.respCode = "0";
                                            tmpRetAtsDetail.transState = tmpBkReader.readedXElement.getSingleText("TRXSTS");

                                            tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("RTNNAR");
                                            if (StringHelper.isNullOrEmpty(tmpRetAtsDetail.respInfo)) {
                                                tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("RJCRSN");
                                            }
                                            if (StringHelper.isNullOrEmpty(tmpRetAtsDetail.respInfo)) {
                                                tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("RJCCOD");
                                            }
                                            tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.respInfo;
                                        } else if (tmpRetCode.equals("0") && tmpRetBkStr[1].indexOf("NTEBPINFZ") < 0) {
                                            if (canBeNotExist(p_req1944, tmpRetAtsDetail)) {
                                                tmpRetAtsDetail.respCode = "0";
                                                tmpRetAtsDetail.transState = PaymentState.FAIL_Payment;
                                                tmpRetAtsDetail.respInfo = "招行不存在该业务参考号";
                                                tmpRetAtsDetail.payInfoCode = "E1302";
                                                tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                                            }
                                        } else {
                                            tmpRetAtsDetail.respCode = "-1";
                                            tmpRetAtsDetail.respInfo = "无/CMBSDKPGK/NTEBPINFZ节点";
                                        }
                                    } else {
                                        tmpRetAtsDetail.respCode = "-1";
                                        tmpRetAtsDetail.respInfo = tmpRetMsg;
                                    }
                                } else {
                                    tmpRetAtsDetail.respCode = "-1";
                                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                                }
                            } else {
                                tmpRetAtsDetail.respCode = "-1";
                                tmpRetAtsDetail.respInfo = tmpRetBkStr[1];
                            }
                        } else if (tmpRetCode.equals("0") && tmpRetBkStr[1].indexOf("NTWAUEBPZ") < 0) {
                            if (canBeNotExist(p_req1944, tmpRetAtsDetail)) {
                                tmpRetAtsDetail.respCode = "0";
                                tmpRetAtsDetail.transState = PaymentState.FAIL_Payment;
                                tmpRetAtsDetail.respInfo = "招行不存在该业务参考号";
                                tmpRetAtsDetail.payInfoCode = "E1302";
                                tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                            }
                        } else {
                            tmpRetAtsDetail.respCode = "-1";
                            tmpRetAtsDetail.respInfo = "无/CMBSDKPGK/NTWAUEBPZ节点";
                        }
                    } else {
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }

        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    //1944 状态查询
    public RetAtsSingle d_1944_QrySglForEBank(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
        try {
            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "NTQRYEBP";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, tmpBnkHeader);
            xmlWriter.writeStartElement("NTWAUEBPY");
            xmlWriter.writeElementString("BUSCOD", "N31010");
            Calendar tmpBGNDAT = Calendar.getInstance();
            tmpBGNDAT.setTime(p_req1944.getBgnDateTime());
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

            Calendar tmpENDDAT = Calendar.getInstance();
            tmpENDDAT.setTime(p_req1944.getBgnDateTime());
            tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

            xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
            xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));
            xmlWriter.writeElementString("MINAMT", "", true);
            xmlWriter.writeElementString("MAXAMT", "", true);
            xmlWriter.writeElementString("YURREF", p_req1944.askNumber);
            xmlWriter.writeElementString("OPRLGN", "", true);
            xmlWriter.writeElementString("AUTSTR", "", true);
            xmlWriter.writeElementString("RTNSTR", "", true);
            xmlWriter.writeElementString("CNVNBR", "", true);
            xmlWriter.writeEndDocument();

            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());

            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        if (tmpBkReader.read("/CMBSDKPGK/NTWAUEBPZ")) {
                            String tmpYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                            tmpRetAtsDetail.reqSeqID = tmpYURREF;
                            if (!p_req1944.askNumber.equals(tmpYURREF)) {
                                throw new Exception("银行返回的支付流水号" + tmpYURREF + "与查询支付流水号" + p_req1944.askNumber + "不符");
                            }
                            tmpRetAtsDetail.respCode = "0";
                            //业务请求状态 REQSTS
                            String tmpREQSTS = tmpBkReader.readedXElement.getSingleText("REQSTS");
                            //业务处理结果 RTNFLG
                            String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                            tmpRetAtsDetail.respInfo = tmpRTNFLG;
                            if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                                tmpRetAtsDetail.transState = tmpREQSTS + "+" + tmpRTNFLG;
                            } else {
                                tmpRetAtsDetail.transState = tmpREQSTS;
                            }
                            tmpRetAtsDetail.payInfoCode = tmpRetAtsDetail.transState;
                        } else if (tmpRetCode.equals("0") && tmpRetBkStr[1].indexOf("NTWAUEBPZ") < 0) {
                            if (canBeNotExist(p_req1944, tmpRetAtsDetail)) {
                                tmpRetAtsDetail.respCode = "0";
                                tmpRetAtsDetail.transState = PaymentState.FAIL_Payment;
                                tmpRetAtsDetail.respInfo = "招行不存在该业务参考号";
                                tmpRetAtsDetail.payInfoCode = "E1302";
                                tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                            }
                        } else {
                            tmpRetAtsDetail.respCode = "-1";
                            tmpRetAtsDetail.respInfo = "无/CMBSDKPGK/NTWAUEBPZ节点";
                        }
                    } else {
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }

        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    //1944 状态查询
    public RetAtsSingle d_1944_QrySglPayOld(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
        try {
            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "GetPaymentInfo";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入通用的头部节点
            //Date tmpDateNow = new Date();
            writeCommonHeader(xmlWriter, tmpBnkHeader);
    /*
      <SDKPAYQYX>
	    <BUSCOD>N02031</BUSCOD>
	    <BGNDAT></BGNDAT>
	    <ENDDAT></ENDDAT>
	    <YURREF></YURREF>
	  </SDKPAYQYX>
	 * */
            xmlWriter.writeStartElement("SDKPAYQYX");
            xmlWriter.writeElementString("BUSCOD", "N02031");
            Calendar tmpBGNDAT = Calendar.getInstance();
            tmpBGNDAT.setTime(p_req1944.getBgnDateTime());
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

            Calendar tmpENDDAT = Calendar.getInstance();
            tmpENDDAT.setTime(p_req1944.getBgnDateTime());
            tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

            xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
            xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));
            xmlWriter.writeElementString("YURREF", p_req1944.askNumber);
            xmlWriter.writeEndDocument();

            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());


            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        if (tmpBkReader.read("/CMBSDKPGK/NTQPAYQYZ")) {
                            String tmpYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                            tmpRetAtsDetail.reqSeqID = tmpYURREF;
                            if (!p_req1944.askNumber.equals(tmpYURREF)) {
                                throw new Exception("银行返回的支付流水号" + tmpYURREF + "与查询支付流水号" + p_req1944.askNumber + "不符");
                            }
                            tmpRetAtsDetail.respCode = "0";
                            //业务请求状态 REQSTS
                            String tmpREQSTS = tmpBkReader.readedXElement.getSingleText("REQSTS");
                            //业务处理结果 RTNFLG
                            String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                            if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                                tmpRetAtsDetail.transState = tmpREQSTS + "+" + tmpRTNFLG;
                            } else {
                                tmpRetAtsDetail.transState = tmpREQSTS;
                            }
                            String tmpRTNNAR = tmpBkReader.readedXElement.getSingleText("RTNNAR");
                            if (!StringHelper.isNullOrEmpty(tmpRTNNAR)) {
                                tmpRetAtsDetail.respInfo = tmpRTNNAR;
                                tmpRetAtsDetail.payInfoCode = tmpRTNNAR;
                            } else if (!StringHelper.isNullOrEmpty(tmpBkReader.readedXElement.getSingleText("C_RTNFLG"))) {
                                tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("C_RTNFLG");
                            } else if (!StringHelper.isNullOrEmpty(tmpBkReader.readedXElement.getSingleText("C_REQSTS"))) {
                                tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("C_REQSTS");
                            }
                            if (tmpBkReader.readedXElement.getSingleText("TRSAMT") != null) {
                                tmpRetAtsDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TRSAMT");
                            }
                            tmpRetAtsDetail.outTransID = tmpBkReader.readedXElement.getSingleText("REQNBR");
                        } else if (tmpRetCode.equals("0") && tmpRetBkStr[1].indexOf("NTQPAYQYZ") < 0) {
                            if (canBeNotExist(p_req1944, tmpRetAtsDetail)) {
                                tmpRetAtsDetail.respCode = "0";
                                tmpRetAtsDetail.transState = PaymentState.FAIL_Payment;
                                tmpRetAtsDetail.respInfo = "招行不存在该业务参考号";
                                tmpRetAtsDetail.payInfoCode = "E1302";
                                tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                            }
                        } else {
                            tmpRetAtsDetail.respCode = "-1";
                            tmpRetAtsDetail.respInfo = "无/CMBSDKPGK/NTQPAYQYZ节点";
                        }
                    } else {
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
            this.WriteBankLogLn(e);
        }

        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    /**
     * 3.11.支付结果列表查询-按业务参考号 NTQRYSTY
     *
     * @param p_req1944
     * @return
     * @throws Exception
     */
    public RetAtsSingle d_1944_NTQRYSTY(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
        try {
            CMB01Header tmpBnkHeader = new CMB01Header();
            tmpBnkHeader.FUNNAM = "NTQRYSTY";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            //写入通用的头部节点
            //Date tmpDateNow = new Date();
            writeCommonHeader(xmlWriter, tmpBnkHeader);
    /*
      <SDKPAYQYX>
	    <BUSCOD>N02031</BUSCOD>
	    <BGNDAT></BGNDAT>
	    <ENDDAT></ENDDAT>
	    <YURREF></YURREF>
	  </SDKPAYQYX>
	 * */
            xmlWriter.writeStartElement("NTQRYSTYX1");
            xmlWriter.writeElementString("BUSCOD", "N02031");
            Calendar tmpBGNDAT = Calendar.getInstance();
            tmpBGNDAT.setTime(p_req1944.getBgnDateTime());
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

            Calendar tmpENDDAT = Calendar.getInstance();
            tmpENDDAT.setTime(p_req1944.getBgnDateTime());
            tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

            xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
            xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));
            xmlWriter.writeElementString("YURREF", p_req1944.askNumber);
            xmlWriter.writeEndDocument();

            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        if (tmpBkReader.read("/CMBSDKPGK/NTSTLLSTZ")) {
                            String tmpYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                            tmpRetAtsDetail.reqSeqID = tmpYURREF;
                            if (!p_req1944.askNumber.equals(tmpYURREF)) {
                                throw new Exception("银行返回的支付流水号" + tmpYURREF + "与查询支付流水号" + p_req1944.askNumber + "不符");
                            }
                            tmpRetAtsDetail.respCode = "0";
                            //业务请求状态 REQSTS
                            String tmpREQSTS = tmpBkReader.readedXElement.getSingleText("REQSTS");

//                            //业务处理结果 RTNFLG
//                            String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
//                            if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
//                                tmpRetAtsDetail.transState = tmpREQSTS + "+" + tmpRTNFLG;
//                            } else {
//                                tmpRetAtsDetail.transState = tmpREQSTS;
//                            }

                            if ("FIN".equals(tmpREQSTS)) {
                                //业务处理结果 RTNFLG
                                String tmpRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                                if (!StringHelper.isNullOrEmpty(tmpRTNFLG)) {
                                    tmpRetAtsDetail.transState = tmpREQSTS + "+" + tmpRTNFLG;
                                }

                                String tmpRTNNAR = tmpBkReader.readedXElement.getSingleText("RTNNAR");
                                if (!StringHelper.isNullOrEmpty(tmpRTNNAR)) {
                                    tmpRetAtsDetail.respInfo = tmpRTNNAR;
                                    tmpRetAtsDetail.payInfoCode = tmpRTNNAR;
                                } else if (!StringHelper.isNullOrEmpty(tmpBkReader.readedXElement.getSingleText("C_RTNFLG"))) {
                                    tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("C_RTNFLG");
                                } else if (!StringHelper.isNullOrEmpty(tmpBkReader.readedXElement.getSingleText("C_REQSTS"))) {
                                    tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleText("C_REQSTS");
                                }
                                if (tmpBkReader.readedXElement.getSingleText("TRSAMT") != null) {
                                    tmpRetAtsDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TRSAMT");
                                }
                                tmpRetAtsDetail.outTransID = tmpBkReader.readedXElement.getSingleText("REQNBR");
                            } else {
                                tmpRetAtsDetail.transState = tmpREQSTS;
                                tmpRetAtsDetail.payInfoCode = tmpREQSTS;
                                tmpRetAtsDetail.respInfo = tmpRetMsg;
                            }
                        } else if (tmpRetCode.equals("0") && tmpRetBkStr[1].indexOf("NTSTLLSTZ") < 0 && tmpRetBkStr[1].indexOf("NTQPAYQYZ") < 0) {
                            if (canBeNotExist(p_req1944, tmpRetAtsDetail)) {
                                tmpRetAtsDetail.respCode = "0";
                                tmpRetAtsDetail.transState = PaymentState.FAIL_Payment;
                                tmpRetAtsDetail.respInfo = "招行不存在该业务参考号";
                                tmpRetAtsDetail.payInfoCode = "E1302";
                                tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
                            }
                        } else {
                            tmpRetAtsDetail.respCode = "-1";
                            tmpRetAtsDetail.respInfo = "无/CMBSDKPGK/NTSTLLSTZ节点";
                        }
                    } else {
                        tmpRetAtsDetail.respCode = "-1";
                        tmpRetAtsDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetAtsDetail.respCode = "-1";
                    tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetAtsDetail.respCode = "-1";
                tmpRetAtsDetail.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            tmpRetAtsDetail.respCode = "-1";
            tmpRetAtsDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }

        retAts.writeRetDetail(tmpRetAtsDetail);
        return retAts;
    }

    /**
     * 4.3.查询交易概要信息 NTAGCINN
     *
     * @param p_req1944
     * @return
     * @throws Exception
     */
    public RetAtsSingle d_1944_NTAGCINN(ReqQrySingle p_req1944) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        //N03010:代发工资   N03020:代发   N03030:代扣
        String tmpBUSCOD = "N03020";
        CMB01Header tmpBnkHeader = new CMB01Header();
        tmpBnkHeader.FUNNAM = "NTAGCINN";
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter, tmpBnkHeader);//写入通用的头部节点
        xmlWriter.writeStartElement("NTAGCINNY1");
        xmlWriter.writeElementString("BUSCOD", tmpBUSCOD);
        String tmpBUSMOD = getBankConfig().getMapValueByKey("busmod" + tmpBUSCOD, p_req1944.officePurpose);
        xmlWriter.writeElementString("BUSMOD", tmpBUSMOD);
        Calendar tmpBGNDAT = Calendar.getInstance();
        tmpBGNDAT.setTime(p_req1944.getBgnDateTime());
        tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);

        Calendar tmpENDDAT = Calendar.getInstance();
        tmpENDDAT.setTime(p_req1944.getBgnDateTime());
        tmpENDDAT.add(Calendar.DAY_OF_MONTH, 1);

        xmlWriter.writeElementString("BGNDAT", Format.Date8Format.format(tmpBGNDAT.getTime()));
        xmlWriter.writeElementString("ENDDAT", Format.Date8Format.format(tmpENDDAT.getTime()));

        xmlWriter.writeElementString("DATFLG", "A");
        xmlWriter.writeElementClosed("RSV50Z");

        xmlWriter.writeEndDocument();
        boolean isFinished = false;
        String tmpREQNBR = "";

        String tmpStrBatchREQSTA = "";
        String tmpStrBatchRTNFLG = "";
        try {
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        boolean hasMatched = false;
                        while (tmpBkReader.read("/CMBSDKPGK/NTAGCINQZ")) {
                            //String tmpStrC_RTNFLG = tmpBkReader.getFirstText("/CMBSDKPGK/NTQATSQYZ/C_RTNFLG");
                            String tmpStrC_REQSTA = tmpBkReader.readedXElement.getSingleText("C_REQSTA");
                            String tmpStrREQSTA = tmpBkReader.readedXElement.getSingleText("REQSTA");//业务请求状态
                            //业务处理结果//当REQSTA=FIN且RTNFLG=S需检查RSV62Z第一位是否为’P’，是表示部分成功，否则表示全部成功。
                            String tmpStrRTNFLG = tmpBkReader.readedXElement.getSingleText("RTNFLG");
                            String tmpStrSUCAMT = tmpBkReader.readedXElement.getSingleText("SUCAMT");
                            String tmpStrSUCNUM = tmpBkReader.readedXElement.getSingleText("SUCNUM");
                            String tmpStrERRDSP = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                            String tmpStrYURREF = tmpBkReader.readedXElement.getSingleText("YURREF");
                            if (tmpStrYURREF != null && p_req1944.askNumber.equals(tmpStrYURREF)) {
                                tmpREQNBR = tmpBkReader.readedXElement.getSingleText("REQNBR");
                                hasMatched = true;
                                tmpStrBatchREQSTA = tmpStrREQSTA;
                                tmpStrBatchRTNFLG = tmpStrRTNFLG;
                                tmpRetDetail.reqSeqID = tmpStrYURREF;
                                if (tmpStrERRDSP != null && tmpStrERRDSP.length() > 32) {
                                    tmpStrERRDSP = tmpStrERRDSP.substring(0, 33);
                                }
                                if (tmpStrREQSTA.equals("FIN") && tmpStrRTNFLG.equals("F") && StringHelper.isNullOrEmpty(tmpREQNBR)) {
                                    float tmpSUCAMT = Float.parseFloat(tmpStrSUCAMT);
                                    float tmpSUCNUM = Float.parseFloat(tmpStrSUCNUM);
                                    //tmpStrSUCAMT.equals("0.00") && tmpStrSUCNUM.equals("00000")
                                    //查明细
                                    //AGN0025 无一笔入帐成功 查明细
                                    //if (!tmpStrERRDSP.startsWith("AGN0025"))
                                    //{
                                    //}
                                    if (tmpSUCAMT == 0 && tmpSUCNUM == 0) {
                                        tmpRetDetail.respCode = "0";
                                        tmpRetDetail.respInfo = tmpStrERRDSP;
                                        tmpRetDetail.transState = tmpStrREQSTA + "+" + tmpStrRTNFLG;
                                        tmpRetDetail.payInfoCode = tmpStrERRDSP;
                                        isFinished = true;
                                    } else {
                                        tmpRetDetail.respCode = "-1";
                                        tmpRetDetail.respInfo = "成功笔数或成功金额不符合预期";
                                    }
                                } else if (tmpStrREQSTA != null && !tmpStrREQSTA.equals("FIN")) {
                                    /*
                                     *业务请求状态
										AUT	等待审批
										NTE	终审完毕
										WCF	订单待确认（商务支付用）
										BNK	银行处理中
										FIN	完成
										ACK	等待确认(委托贷款用)
										APD 	待银行确认(国际业务用)
										OPR	数据接收中（代发）


										业务处理结果
										取值	含义	说明
										S	成功	银行支付成功
										F	失败	银行支付失败
										B	退票	银行支付被退票
										R	否决	企业审批否决
										D	过期	企业过期不审批
										C	撤消	企业撤销
										M	商户撤销订单	商务支付
										V	拒绝	委托贷款被借款方拒绝
                                     * */
                                    tmpRetDetail.respCode = "0";
                                    tmpRetDetail.respInfo = tmpStrC_REQSTA;
                                    tmpRetDetail.transState = tmpStrREQSTA;
                                    tmpRetDetail.payInfoCode = tmpStrREQSTA;
                                    isFinished = true;
                                } else if (StringHelper.isNullOrEmpty(tmpStrREQSTA)) {
                                    tmpRetDetail.respCode = "-1";
                                    tmpRetDetail.respInfo = "批次的业务请求状态为空";
                                }
                                break;
                            }
                        }
                        if (hasMatched == false) {
                            if (getBankConfig().getValueAsString("canBeFailed").contains(p_req1944.askNumber)) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.transState = "PaymentFailed";
                                tmpRetDetail.payInfoCode = "";
                                tmpRetDetail.respInfo = tmpRetMsg;
                                tmpRetDetail.reqSeqID = p_req1944.askNumber;
                                isFinished = true;
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "银行未返回该批次相关信息";
                            }
                        }
                    } else if (getBankConfig().getValueAsString("canBeFailed").contains(p_req1944.askNumber) && getBankConfig().getValueAsString("canBeFailedMsg").contains(tmpRetMsg)) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.transState = "PaymentFailed";
                        tmpRetDetail.payInfoCode = "";
                        tmpRetDetail.respInfo = tmpRetMsg;
                        tmpRetDetail.reqSeqID = p_req1944.askNumber;
                        isFinished = true;
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }

        if (isFinished || "-1".equals(tmpRetDetail.respCode)) {
            if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(p_req1944.askNumber)) {
                tmpRetDetail.reqSeqID = p_req1944.askNumber;
            }
            retAts.writeRetDetail(tmpRetDetail);
            return retAts;
        }

        if (!p_req1944.askNumber.equals(tmpRetDetail.reqSeqID)) {
            throw new Exception("取招行流水号出错，请求值为" + p_req1944.askNumber + "，取到值为" + tmpRetDetail.reqSeqID);
        }
        if (StringHelper.isNullOrEmpty(tmpREQNBR)) {
            throw new Exception("招行流水号为空");
        }

        //查明细
        tmpBnkHeader.FUNNAM = "GetAgentDetail";
        xmlWriter = null;
        xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter, tmpBnkHeader);//写入通用的头部节点
        xmlWriter.writeStartElement("SDKATDQYX");//
        xmlWriter.writeElementString("REQNBR", tmpREQNBR);
        xmlWriter.writeEndDocument();
        try {
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/RETCOD");
                    String tmpRetMsg = tmpBkReader.getFirstText("/CMBSDKPGK/INFO/ERRMSG");
                    if (tmpRetCode != null && tmpRetCode.equals("0")) {
                        if (tmpBkReader.read("/CMBSDKPGK/NTQATDQYZ")) {
                            String tmpReqSeqID = tmpRetDetail.reqSeqID;
                            tmpRetDetail = new RetAtsSglDetail();
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TRSAMT");
                            tmpRetDetail.reqSeqID = tmpReqSeqID;//tmpBkReader.readedXElement.getSingleText("TRSDSP");
                            tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpBkReader.readedXElement.getSingleText("STSCOD");
                            String bkSTSCOD = tmpBkReader.readedXElement.getSingleText("STSCOD");
                            if ("F".equals(tmpStrBatchRTNFLG) && "I".equals(bkSTSCOD)) {
                                tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpStrBatchRTNFLG + "+" + bkSTSCOD;
                            } else if ("F".equals(tmpStrBatchRTNFLG) && "S".equals(bkSTSCOD)) {
                                tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpStrBatchRTNFLG + "+" + bkSTSCOD;
                            } else if ("S".equals(tmpStrBatchRTNFLG) && ("F".equals(bkSTSCOD) || "E".equals(bkSTSCOD))) {
                                tmpRetDetail.transState = tmpStrBatchREQSTA + "+" + tmpStrBatchRTNFLG + "+" + bkSTSCOD;
                            }
                            tmpRetDetail.respInfo = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                            tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ERRDSP");
                            if (tmpRetDetail.payInfoCode != null && tmpRetDetail.payInfoCode.length() > 32) {
                                tmpRetDetail.payInfoCode = tmpRetDetail.payInfoCode.substring(0, 33);
                            }

                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpRetMsg;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception e) {
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.getMessage();
            e.printStackTrace();
        }
        if ("-1".equals(tmpRetDetail.respCode) && StringHelper.isNullOrEmpty(p_req1944.askNumber)) {
            tmpRetDetail.reqSeqID = p_req1944.askNumber;
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingle d_1944_QrySglPayByNotice(ReqQrySingle p_req1944) throws Exception {

        NoticeDataHelper noticeHelper = new NoticeDataHelper(this.bankFront.tenant, new Date());
        try {
            SinglePayNotice payNotice = noticeHelper.loadData(p_req1944.askNumber, p_req1944.reqHeader.bankCode);
            if (payNotice != null) {
                if (payNotice.reqSeqID.equals(p_req1944.askNumber)) {
                    if ("FIN+S".equals(payNotice.transState) || "FIN+F".equals(payNotice.transState) || "FIN+B".equals(payNotice.transState)
                            || "FIN+F+B".equals(payNotice.transState) || "FIN+R".equals(payNotice.transState)
                            || "FIN+D".equals(payNotice.transState) || "FIN+V".equals(payNotice.transState)
                            || "FIN+C".equals(payNotice.transState) || "FIN+M".equals(payNotice.transState)) {
                        //返回ATS的对象
                        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
                        RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
                        tmpRetAtsDetail.respCode = "0";
                        tmpRetAtsDetail.reqSeqID = payNotice.reqSeqID;
                        tmpRetAtsDetail.transState = payNotice.transState;
                        tmpRetAtsDetail.respInfo = payNotice.payInfo;
                        tmpRetAtsDetail.payInfoCode = payNotice.payInfoCode;
                        tmpRetAtsDetail.transAmt = payNotice.transAmt;
                        tmpRetAtsDetail.outTransID = payNotice.outTransID;
                        retAts.writeRetDetail(tmpRetAtsDetail);
                        return retAts;
                    }
                } else {
                    this.WriteBankLogAndLimit("noticeHelper.loadData加载reqSeqID值" + payNotice.reqSeqID + "与请求值" + p_req1944.askNumber + "不符");
                }
            }
        } catch (Exception ex) {
            WriteBankLogLn(ex);
        } finally {
            noticeHelper.close();
        }
        return null;
        
        /*
        try {
        	
        	
            
        	
            HashMap<String, String> hashNotice = new HashMap<String, String>();
            List<Map<String, Object>> listMap = DirectHelper.getSinglePayNotice(p_req1944.reqHeader.bankCode, p_req1944.askNumber, "order by transstate");
            if (listMap != null && listMap.size() > 0) {
                for (int i = 0; i < listMap.size(); i++) {
                    Map<String, Object> eachSeq = listMap.get(i);
                    //<RTNFLG>B</RTNFLG>
                    RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
                    tmpRetDetail.respCode = String.valueOf(eachSeq.get("respCode".toUpperCase()));
                    tmpRetDetail.reqSeqID = String.valueOf(eachSeq.get("reqSeqID".toUpperCase()));
                    tmpRetDetail.transState = String.valueOf(eachSeq.get("transState".toUpperCase()));
                    tmpRetDetail.respInfo = String.valueOf(eachSeq.get("respInfo".toUpperCase()));
                    tmpRetDetail.payInfoCode = String.valueOf(eachSeq.get("payInfoCode".toUpperCase()));
                    tmpRetDetail.transAmt = String.valueOf(eachSeq.get("transAmt".toUpperCase()));
                    if (!hashNotice.containsKey(tmpRetDetail.reqSeqID)) {
                        retAts.writeRetDetail(tmpRetDetail);
                        hashNotice.put(tmpRetDetail.reqSeqID, tmpRetDetail.reqSeqID);
                    }
                }
            }

            int waitMins = this.getBankConfig().getValueAsInt("qry1944WaitMins");
            if (waitMins > 0) {
                double pastMins = DateHelper.getDifferMins(new Date(), p_req1944.getBgnDateTime());
                if (pastMins >= waitMins) {
                    if (!hashNotice.containsKey(p_req1944.askNumber)) {//未接收到通知
                        RetAtsSingle retQry = d_1944_QrySglPay(p_req1944);
                        retAts.writeRetDetail(retQry.retDetail);
                    }
                } else {
                    this.WriteBankLogLn("未到直接查询的时间，直接返回已通知的结果");
                }
            } else {
                this.WriteBankLogLn("未设置直接查询的时间，直接返回已通知的结果");
            }
            

        } catch (Exception e) {
            WriteBankLogLn(e);
        }
        */

    }


    /**
     * 3.3	查询支付结果
     * <p>
     * 单笔合批支付查询
     */
    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
        retAts.reqBatchNO = p_req1944BAT.reqBatchNO;

        try {
            retAts.batRespCode = "0";
            while (p_req1944BAT.readRecord()) {
                ReqQrySglBatPayDetail tmpDetail = p_req1944BAT.readedDetail;
                ReqQrySingle tmpReq1944 = new ReqQrySingle(tmpDetail, p_req1944BAT.reqHeader);
                RetAtsSingle retQry = d_1944_QrySglPay(tmpReq1944);
                retAts.writeRetDetail(retQry.retDetail);
            }

        } catch (Exception ex) {

            WriteBankLogLn(ex);
            retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
            retAts.batRespCode = "-1";
            retAts.batRespInfo = ex.getMessage();
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
